﻿using System;
using System.ComponentModel;
using System.Windows;
using Prometheus.Binding.Core;
using Prometheus.Binding.ReadOnly;
using Prometheus.TypeUtility;
using Telerik.Windows.Controls;
#if SILVERLIGHT
#if WINDOWS_PHONE
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using Telerik.Windows.Controls;

#else
using Telerik.Windows.Controls;
#endif
#else
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
#endif

namespace Prometheus.Binding.RadSupport
{
    public static class proRadBindingInitializer
    {
         public static void Initialize()
         {
#if WINDOWS_PHONE
             RegisterDefaultProperties();
#endif
             RegisterBindingInitialization();
         }
#if WINDOWS_PHONE
        private static void RegisterDefaultProperties()
        {
            proBindingBase.RegisterDefaultElementPropertyPath<RadDatePicker>("Value");
            proBindingBase.RegisterDefaultElementPropertyPath<RadAutoCompleteBox>("Text");
            proBindingBase.RegisterDefaultElementPropertyPath<RadBusyIndicator>("IsRunning");
            proBindingBase.RegisterDefaultElementPropertyPath<RadCalendar>("SelectedValue");
            proBindingBase.RegisterDefaultElementPropertyPath<RadDateSelector>("SelectedValue");
            proBindingBase.RegisterDefaultElementPropertyPath<RadDataBoundListBox>("SelectedValue");
            proBindingBase.RegisterDefaultElementPropertyPath<RadListPicker>("SelectedItem");
            proBindingBase.RegisterDefaultElementPropertyPath<RadNumericUpDown>("Value");
            proBindingBase.RegisterDefaultElementPropertyPath<RadRating>("Value");
            proBindingBase.RegisterDefaultElementPropertyPath<RadTextBox>("Text");
            proBindingBase.RegisterDefaultElementPropertyPath<RadTimePicker>("Value");
            proBindingBase.RegisterDefaultElementPropertyPath<RadTimeSelector>("SelectedValue");
            proBindingBase.RegisterDefaultElementPropertyPath<RadToggleSwitch>("IsChecked");
        }
#endif

        private static void RegisterBindingInitialization()
        {

#if WINDOWS_PHONE
            proBindingBase.RegisterControlForBindingInitialization<RadToggleSwitch>((element, isInitializing, binding) =>
                {
                    var toggleSwitch = (RadToggleSwitch) element;
                    if(isInitializing)
                    {
                        toggleSwitch.CheckedChanged+=ToggleSwitchOnCheckedChanged;
                    }
                    else
                    {
                        toggleSwitch.CheckedChanged -= ToggleSwitchOnCheckedChanged;
                    }
                });

            proBindingBase.RegisterControlForBindingInitialization<RadTextBox>((element, isInitializing, binding) =>
                {
                    var radTextBox = (RadTextBox) element;
                    if(isInitializing)
                    {
                        radTextBox.TextChanged += RadTextBoxOnTextChanged;
                    }
                    else
                    {
                        radTextBox.TextChanged -= RadTextBoxOnTextChanged;
                    }
                });

            proBindingBase.RegisterControlForBindingInitialization<RadRating>((element, isInitializing, binding) =>
                {
                    var radRating = (RadRating) element;
                    if(isInitializing)
                    {
                        radRating.ValueChanged+=RadRatingOnValueChanged;
                    }
                    else
                    {
                        radRating.ValueChanged -= RadRatingOnValueChanged;
                    }
                });

            proBindingBase.RegisterControlForBindingInitialization<RadSelector>((element, isInitializing, binding) =>
            {
                var selector = (Selector)element;
                if (isInitializing)
                {
                    selector.SelectionChanged += SelectorOnSelectionChanged;
                }
                else
                {
                    selector.SelectionChanged -= SelectorOnSelectionChanged;
                }
            });

            proBindingBase.RegisterControlForBindingInitialization<RadDateSelector>((element, isInitializing, binding) =>
                {
                    var dateSelector = (RadDateSelector) element;
                    if(isInitializing)
                    {
                        dateSelector.SelectedValueChanged += DateSelectorOnSelectedValueChanged;
                    }
                    else
                    {
                        dateSelector.SelectedValueChanged -= DateSelectorOnSelectedValueChanged;
                    }
                });
            
            proBindingBase.RegisterControlForBindingInitialization<RadAutoCompleteBox>((element, isInitializing, binding) =>
                {
                    var autoCompleteBox = (RadAutoCompleteBox) element;
                    if (isInitializing)
                    {
                        autoCompleteBox.PropertyChanged += AutoCompleteBoxOnPropertyChanged;
                    }
                    else
                    {
                        autoCompleteBox.PropertyChanged -= AutoCompleteBoxOnPropertyChanged;
                    }
                });

            proBindingBase.RegisterControlForBindingInitialization<RadDatePicker>((element, isInitializing, binding) =>
                {
                    var radDatePicker = (RadDatePicker) element;
                    if(isInitializing)
                    {
                        radDatePicker.ValueChanged += RadDatePickerOnValueChanged;
                    }
                    else
                    {
                        radDatePicker.ValueChanged -= RadDatePickerOnValueChanged;
                    }
                });
            proBindingBase.RegisterControlForBindingInitialization<RadCalendar>((element, isInitializing, binding) =>
            {
                var radCalendar = (RadCalendar)element;
                if (isInitializing)
                {
                    radCalendar.SelectedValueChanged += RadCalendarOnSelectedValueChanged;
                }
                else
                {
                    radCalendar.SelectedValueChanged -= RadCalendarOnSelectedValueChanged;
                }
            });
            proBindingBase.RegisterControlForBindingInitialization<PasswordBox>((element, isInitializing, binding) =>
            {
                var passwordBox = (PasswordBox)element;
                if (isInitializing)
                {
                    passwordBox.PasswordChanged += PasswordBoxOnPasswordChanged;
                }
                else
                {
                    passwordBox.PasswordChanged -= PasswordBoxOnPasswordChanged;
                }
            });

#else
            proBindingBase.RegisterControlForBindingInitialization<RadCalendar>((element, isInitializing, binding) =>
            {
                var radCalendar = (RadCalendar)element;
                if (isInitializing)
                {
                    radCalendar.SelectionChanged += RadCalendarOnSelectionChanged;
                }
                else
                {
                    radCalendar.SelectionChanged -= RadCalendarOnSelectionChanged;
                }
            });


#endif



            proBindingBase.RegisterControlForBindingInitialization<Selector>((element, isInitializing, binding) =>
                {
                    var selector = (Selector) element;
                    if(isInitializing)
                    {
                        selector.SelectionChanged+= SelectorOnSelectionChanged;
                    }
                    else
                    {
                        selector.SelectionChanged -= SelectorOnSelectionChanged;
                    }
                });
        }



        private static void RadCalendarOnSelectionChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
        {
            UpdateRelatedBindings(sender);
        }

#if WINDOWS_PHONE

        private static void PasswordBoxOnPasswordChanged(object sender, RoutedEventArgs routedEventArgs)
        {
            UpdateRelatedBindings(sender);
        }

        private static void ToggleSwitchOnCheckedChanged(object sender, CheckedChangedEventArgs checkedChangedEventArgs)
        {
            UpdateRelatedBindings(sender);
        }

        private static void RadTextBoxOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
        {
            UpdateRelatedBindings(sender);
        }

        private static void RadRatingOnValueChanged(object sender, ValueChangedEventArgs<object> valueChangedEventArgs)
        {
            UpdateRelatedBindings(sender);
        }

        private static void DateSelectorOnSelectedValueChanged(object sender, ValueChangedEventArgs<DateTime> args)
        {
            UpdateRelatedBindings(sender);
        }

        private static void RadCalendarOnSelectedValueChanged(object sender, ValueChangedEventArgs<object> e)
        {
            UpdateRelatedBindings(sender);
        }

        

        private static void AutoCompleteBoxOnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            UpdateRelatedBindings(sender);
        }

        private static void RadDatePickerOnValueChanged(object sender, ValueChangedEventArgs<object> args)
        {
            UpdateRelatedBindings(sender);
        }
#endif
        private static void UpdateRelatedBindings(object sender)
        {
            var bindings = proForm.GetBindingsByElement((UIElement)sender);
            foreach (var binding in bindings)
            {
                binding.UpdateSource();
            }
        }

        private static void SelectorOnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                var selector = (Selector)sender;

                var newValue = e.AddedItems[0].GetProperty(selector.SelectedValuePath);
                var bindings = proForm.GetBindingsByElement(selector);

                foreach (var binding in bindings)
                {
                    if (binding.Path == "SelectedValue")
                    {
                        binding.ProcessValueToData(newValue);
                    }
                    else
                    {
                        binding.UpdateSource();
                    }
                }
            }
            catch (IndexOutOfRangeException)
            {

            }
        }
    }
}